package com.example.ojcodesandbox.codesandbox;

import com.example.ojcodesandbox.utils.CodeUtils;
import com.example.ojcommon.common.ExecuteCodeRequest;
import com.example.ojcommon.common.ExecuteCodeResponse;
import com.example.ojcommon.enums.SubmitReturnEnum;
import com.example.ojcommon.exception.BusinessException;
import com.example.ojcommon.common.JudgeInfo;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.List;

@Slf4j
public abstract class AbstractCompileTemplate implements CodeSandbox {

    public static final String GLOBAL_CODE_DIR_NAME = "tempCode";

    public static final String GLOBAL_CODE_NAME = "Main";

    public ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest, String image, String[] runCommand, String compileCommand) {
        List<String> inputList = executeCodeRequest.getInputList();
        ExecuteCodeResponse executeCodeResponse = new ExecuteCodeResponse();
        //1. 把用户的代码保存为文件
        File codeFile = createFile(executeCodeRequest);
        //2. 编译代码
        try {
            compileFile(compileCommand,codeFile);
            //3. 执行代码，得到输出结果,收集整理输出结果
            executeCodeResponse = runFile(codeFile.getParentFile().getAbsolutePath(), inputList, image, runCommand);
        } catch (BusinessException e) {
            JudgeInfo judgeInfo = new JudgeInfo();
            judgeInfo.setMessage(SubmitReturnEnum.RUNNING_WRONG);
            executeCodeResponse.setJudgeInfo(judgeInfo);
        } catch (Exception e) {
            JudgeInfo judgeInfo = new JudgeInfo();
            judgeInfo.setMessage(SubmitReturnEnum.COMPILE_WRONG);
            executeCodeResponse.setJudgeInfo(judgeInfo);
        } finally {
            executeCodeResponse.setQuestionId(executeCodeRequest.getQuestionId());
            executeCodeResponse.setSubmitId(executeCodeRequest.getSubmitId());
            //4. 文件清理
            boolean b = deleteFile(codeFile.getParentFile());
            if (!b) {
                log.error("deleteFile error, userCodeFilePath = {}", codeFile.getAbsolutePath());
            }
        }
        return executeCodeResponse;
    }

    public File createFile(ExecuteCodeRequest executeCodeRequest) {
        return CodeUtils.createFile(executeCodeRequest.getCode(), executeCodeRequest.getLanguage());
    }

    public abstract void compileFile(String command, File file) throws Exception;

    public ExecuteCodeResponse runFile(String codeParentPath, List<String> inputList, String images, String[] command) {
        return CodeUtils.runFile(codeParentPath, inputList, images, command);
    }

    public boolean deleteFile(File codeParentFile) {
        return CodeUtils.deleteFile(codeParentFile);
    }
}
